﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Text;

namespace WcfServiceDuplex
{
	// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together.
	[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
	[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
	public class Service1 : IMyService
	{
		#region Member Variables

		public delegate void MessageEventHandler(object sender, EventArgs e);
		//The event when raised has to be invoked for all the subscribed clients and hence made static.
		public static event MessageEventHandler Broadcast;

		IMyCallback _callbackInstance;

		public static string m_message = String.Empty;
		public static string m_id = String.Empty;

		#endregion

		public void SendMessage(string str)
		{
			string data = str.Replace("a", "w");
			IMyCallback callback = OperationContext.Current.GetCallbackChannel<IMyCallback>();
			callback.SendMessageCallback(data);
		}

		public void SendUserMessage(string userId, string Message)
		{
			m_id = userId;
			m_message = Message;

			Console.WriteLine(DateTime.Now + " : " + userId + " has sent a message.");

			Iterate(new EventArgs());
		}

		public void Join(string userId)
		{
			_callbackInstance = OperationContext.Current.GetCallbackChannel<IMyCallback>();
			Broadcast += new MessageEventHandler(RaiseBroadcastEvent);
		}

		public void Leave(string userId)
		{
			Broadcast -= new MessageEventHandler(RaiseBroadcastEvent);
		}

		void RaiseBroadcastEvent(object sender, EventArgs e)
		{
			_callbackInstance.ReceiveMessage(string.Format("{0} : {1}", m_id, m_message));
		}

		void Iterate(EventArgs e)
		{
			if (Broadcast != null)
			{
				foreach (MessageEventHandler handler in Broadcast.GetInvocationList())
				{
					handler.BeginInvoke(this, e, null, null);
				}
			}
		}
	}
}
